package com.zqwm.fly.mongo;

import com.zqwm.fly.types.PageModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.lang.reflect.ParameterizedType;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@SuppressWarnings("all")
@Repository
public class Mongodb<T>
{
    private static final Logger logger = LoggerFactory.getLogger(Mongodb.class);

    @Autowired
    protected MongoTemplate mongoTemplate;

    private Class<?> clz;

    public Class<?> getClz()
    {
        if(clz==null)
        {
            //获取泛型的Class对象
            clz = ((Class<?>) (((ParameterizedType)(this.getClass().getGenericSuperclass())).getActualTypeArguments()[0]));
        }
        return clz;
    }

    //创建对象
    public boolean insert(T entity,String collection)
    {
        mongoTemplate.save(entity,collection);
        return true;
    }

    //创建对象
    public boolean insert(T entity)
    {
        mongoTemplate.save(entity);
        return true;
    }

    //根据多条件删除
    public boolean delete(String collection,Map<String, Object> whereMap)
    {
        Query query = new Query();

        if ((whereMap != null) && (!(whereMap.isEmpty())))
        {
            for (String key : whereMap.keySet())
            {
                query.addCriteria(new Criteria(key).is(whereMap.get(key)));
            }
        }

        mongoTemplate.remove(query,collection);

        return true;
    }

    //批量删除,清空集合
    public boolean deleteAll(T entity)
    {
        mongoTemplate.dropCollection(entity.getClass());
        return true;
    }

    //修改
    public boolean update(Map<String, Object> whereMap, Map<String, Object> setMap)
    {
        Query query = new Query();

        if ((whereMap != null) && (!(whereMap.isEmpty())))
        {
            for (String key : whereMap.keySet())
            {
                query.addCriteria(new Criteria(key).is(whereMap.get(key)));
            }
        }

        Update update = new Update();

        if ((setMap != null) && (!(setMap.isEmpty())))
        {
            for (String key : setMap.keySet()) {update.set(key, setMap.get(key));}
        }

        mongoTemplate.findAndModify(query, update,getClz());

        return true;
    }

    //修改
    public boolean update(Map<String, Object> whereMap, Map<String, Object> setMap,String cellection)
    {
        Query query = new Query();

        if ((whereMap != null) && (!(whereMap.isEmpty())))
        {
            for (String key : whereMap.keySet())
            {
                query.addCriteria(new Criteria(key).is(whereMap.get(key)));
            }
        }

        Update update = new Update();

        if ((setMap != null) && (!(setMap.isEmpty())))
        {
            for (String key : setMap.keySet()) {update.set(key, setMap.get(key));}
        }

        mongoTemplate.findAndModify(query, update,getClz(),cellection);

        return true;
    }

    //查询单个对象
    public List<T> find(Map<String, Object> whereMap)
    {
        Criteria criteria = new Criteria();

        for (Iterator iter = whereMap.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();

            criteria.andOperator(Criteria.where(name).is(whereMap.get(name)));
        }

        Query query = new Query(criteria);


        return (List<T>)this.mongoTemplate.find(query, getClz());
    }


    //多条件查询一条数据
    public T findOneByItems(Map<String, Object> params)
    {
        Query query = new Query();
        if ((params != null) && (!(params.isEmpty())))
        {
            for (String key : params.keySet())
            {
                query.addCriteria(new Criteria(key).is(params.get(key)));
            }
        }

        return (T)mongoTemplate.findOne(query, getClz());
    }

    //多条件查询一条数据
    public T findOneByItems(Map<String, Object> params,String cellection)
    {
        Query query = new Query();
        if ((params != null) && (!(params.isEmpty())))
        {
            for (String key : params.keySet())
            {
                //query.addCriteria(new Criteria(key).is(params.get(key)));
                query.addCriteria(Criteria.where(key).is(params.get(key)));
            }
        }

        return (T)mongoTemplate.find(query, getClz(),cellection).get(0);
    }

    //创建集合
    public void createCollection(T object)
    {
        if (!this.mongoTemplate.collectionExists(getClz()))
        {
            this.mongoTemplate.createCollection(getClz());
        }

    }

    //根据多条件统计数量
    public long count(Map<String, Object> params)
    {
        Query query = new Query();
        if ((params != null) && (!(params.isEmpty())))
        {
            for (String key : params.keySet()) {
                query.addCriteria(new Criteria(key).is(params.get(key)));
            }
        }

        return (long)mongoTemplate.find(query, getClz()).size();
    }

    //多条件查询list
    public List<T> findByItems(Map<String, Object> params,String cellection)
    {
        Query query = new Query();
        if ((params != null) && (!(params.isEmpty())))
        {
            for (String key : params.keySet()){query.addCriteria(new Criteria(key).is(params.get(key)));}
        }

        return (List<T>)this.mongoTemplate.find(query, getClz(),cellection);
    }

    //根据ID跟新数据
    public void update(String id, Map<String, Object> params,T t)
    {
        Query query = new Query();
        query.addCriteria(new Criteria("_id").is(id));
        Update update = new Update();
        if ((params != null) && (!(params.isEmpty())))
        {
            for (String key : params.keySet()) {
                update.set(key, params.get(key));
            }
        }

        this.mongoTemplate.updateFirst(query,update,getClz());
    }

    //根据ID删除数据
    public void deleteById(String id) {mongoTemplate.remove(new Query(Criteria.where("_id").is(id)), getClz());}

    //分页 排序 多条件过滤
    public PageModel<T> findByPage(PageModel<T> page,Integer pageIndex,Integer pageSize,Map<String, Object> params, String cellection)
    {

        //创建排序模板Sort
        Sort sort = new Sort(Sort.Direction.DESC, "id");

        //创建分页模板Pageable
        Pageable pageable = new PageRequest(pageIndex-1, pageSize, sort);

        //创建查询条件对象
        Query query = new Query();
        if ((params != null) && (!(params.isEmpty())))
        {
            for (String key : params.keySet())
            {
                //精确查询
                //query.addCriteria(Criteria.where(key).is(params.get(key)));
                //模糊查询
                query.addCriteria(Criteria.where(key).regex(".*?\\" +params.get(key).toString()+ ".*"));
            }
        }

        //mongoTemplate.count计算总数
        long total = mongoTemplate.count(query,getClz(),cellection);
        page.setRowCount((int)total);
        // mongoTemplate.find 查询结果集
        List<T> items = (List<T>) mongoTemplate.find(query.with(pageable),getClz(),cellection);

        page.setPageNo(pageIndex);
        page.setPageSize(pageSize);
        page.setDatas(items);

        return page;
    }

}
